﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data;
using System.Data.SqlClient;

using SIPO.Library;
using SIPO.Library.DomainObject.Transaction;
using SIPO.Library.Enum;
using SIPO.Library.Interfaces;
using SIPO.Library.DomainObject.Administration.Catalog;

namespace SIPO.Library.DataAccess.Transaction
{
    public partial class recAcceptanceRepo
    {

        public int ValidateAcceptancePeriod(int period)
        {
            int result = -1;

            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = @"
                                select count(recAcceptance.AcceptancePeriod) as jumlah 
                                from transactions.recAcceptance
                                where AcceptancePeriod = " + period;
                    cmd.CommandType = CommandType.Text;

                    try
                    {
                        conn.Open();
                        var objId = cmd.ExecuteScalar();
                        result = objId == DBNull.Value ? -1 : int.Parse(objId.ToString());
                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
            return result;
        }

        public int ValidateSkNo(string skNo)
        {
            int result = -1;

            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = @"
                                select count(recAcceptance.SkNo) as jumlah 
                                from transactions.recAcceptance 
                                where SkNo = '" + skNo + "'";
                    cmd.CommandType = CommandType.Text;

                    try
                    {
                        conn.Open();
                        var objId = cmd.ExecuteScalar();
                        result = objId == DBNull.Value ? -1 : int.Parse(objId.ToString());
                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
            return result;
        }

        public void Review(recAcceptance domain)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = " UPDATE transactions.recAcceptance SET ReviewDate = @ReviewDate, UpdatedDate = @UpdatedDate, UpdatedBy = @UpdatedBy where AcceptanceId = @AcceptanceId ";
                    cmd.CommandType = CommandType.Text;
                    cmd.Parameters.Add("@AcceptanceId", SqlDbType.Int).Value = domain.AcceptanceId;
                    cmd.Parameters.Add("@ReviewDate", SqlDbType.Date).Value = (object)domain.ReviewDate ?? DBNull.Value;
                    cmd.Parameters.Add("@UpdatedDate", SqlDbType.DateTime).Value = (object)domain.UpdatedDate ?? DBNull.Value;
                    cmd.Parameters.Add("@UpdatedBy", SqlDbType.VarChar).Value = (object)domain.UpdatedBy ?? DBNull.Value;

                    try
                    {
                        conn.Open();
                        cmd.ExecuteNonQuery();

                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
        }

        public void UnReview(recAcceptance domain)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = " UPDATE transactions.recAcceptance SET ReviewDate = @ReviewDate, UpdatedDate = @UpdatedDate, UpdatedBy = @UpdatedBy WHERE AcceptanceId = @AcceptanceId ";
                    cmd.CommandType = CommandType.Text;
                    cmd.Parameters.Add("@AcceptanceId", SqlDbType.Int).Value = domain.AcceptanceId;
                    cmd.Parameters.Add("@ReviewDate", SqlDbType.Date).Value = (object)domain.ReviewDate ?? DBNull.Value;
                    cmd.Parameters.Add("@UpdatedDate", SqlDbType.DateTime).Value = (object)domain.UpdatedDate ?? DBNull.Value;
                    cmd.Parameters.Add("@UpdatedBy", SqlDbType.VarChar).Value = (object)domain.UpdatedBy ?? DBNull.Value;

                    try
                    {
                        conn.Open();
                        cmd.ExecuteNonQuery();

                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
        }

        public object SelectScalar(SQL.Function.Aggregate function, string column, string parameter)
        {
            object _result = null;
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    StringBuilder sbQuery = new StringBuilder();
                    switch (function)
                    {
                        case SQL.Function.Aggregate.Max:
                            sbQuery.AppendFormat("SELECT MAX({0}) FROM transactions.recAcceptance {1}", column, parameter);
                            break;
                        case SQL.Function.Aggregate.Min:
                            sbQuery.AppendFormat("SELECT MIN({0}) FROM transactions.recAcceptance {1}", column, parameter);
                            break;
                        case SQL.Function.Aggregate.Distinct:
                            sbQuery.AppendFormat("SELECT DISTINCT({0}) FROM transactions.recAcceptance {1}", column, parameter);
                            break;
                        case SQL.Function.Aggregate.Count:
                            sbQuery.AppendFormat("SELECT COUNT({0}) FROM transactions.recAcceptance {1}", column, parameter);
                            break;
                        case SQL.Function.Aggregate.Sum:
                            sbQuery.AppendFormat("SELECT SUM({0}) FROM transactions.recAcceptance {1}", column, parameter);
                            break;
                        case SQL.Function.Aggregate.Avg:
                            sbQuery.AppendFormat("SELECT AVG({0}) FROM transactions.recAcceptance {1}", column, parameter);
                            break;
                        default:
                            // do nothing 
                            break;
                    }

                    cmd.CommandText = sbQuery.ToString();
                    cmd.CommandType = CommandType.Text;
                    try
                    {
                        conn.Open();
                        _result = cmd.ExecuteScalar();
                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
            return _result;
        }

        public List<recAcceptance> GetList(int pageSize, int currentPage, string sortName, string sortOrder, string parameters)
        {
            List<recAcceptance> tt = new List<recAcceptance>();
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    int startRow = ((currentPage - 1) * pageSize) + 1;
                    int endRow = (startRow + pageSize);

                    StringBuilder sbQuery = new StringBuilder();
                    sbQuery.AppendFormat(" WITH result_set AS ");
                    sbQuery.AppendFormat(" ( ");
                    sbQuery.AppendFormat("    SELECT ");
                    sbQuery.AppendFormat("      ROW_NUMBER() OVER (ORDER BY {0} {1}) AS [row_number], ", sortName, sortOrder);
                    sbQuery.AppendFormat("      AcceptanceId, AcceptancePeriod, SkNo, SkDate, EntryDate, ReviewDate, sumValues, CreatedDate, CreatedBy, UpdatedDate, CASE WHEN recAcceptance.Versi = (SELECT MAX(mst.Versi) FROM transactions.recAcceptance mst where mst.AcceptancePeriod = recAcceptance.AcceptancePeriod) THEN 'max' ELSE recAcceptance.UpdatedBy END UpdatedBy, Versi ");
                    sbQuery.AppendFormat("    FROM ");
                    sbQuery.AppendFormat("      transactions.recAcceptance ");
                    sbQuery.AppendFormat(" {0} ", parameters);
                    sbQuery.AppendFormat(" ) ");
                    sbQuery.AppendFormat(" SELECT * FROM result_set WHERE [row_number] BETWEEN {0} AND {1} ", startRow, endRow);

                    cmd.CommandText = sbQuery.ToString();
                    cmd.CommandType = CommandType.Text;

                    try
                    {
                        conn.Open();
                        using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                        {
                            while (dr.Read())
                            {
                                recAcceptance t = new recAcceptance();
                                t.AcceptanceId = dr[recAcceptance.Fields.AcceptanceId] == DBNull.Value ? 0 : int.Parse(dr[recAcceptance.Fields.AcceptanceId].ToString());
                                t.AcceptancePeriod = dr[recAcceptance.Fields.AcceptancePeriod] == DBNull.Value ? 0 : int.Parse(dr[recAcceptance.Fields.AcceptancePeriod].ToString());
                                t.SkNo = dr[recAcceptance.Fields.SkNo] == DBNull.Value ? string.Empty : dr[recAcceptance.Fields.SkNo].ToString();
                                t.SkDate = dr[recAcceptance.Fields.SkDate] == DBNull.Value ? DateTime.Now : DateTime.Parse(dr[recAcceptance.Fields.SkDate].ToString());
                                t.EntryDate = dr[recAcceptance.Fields.EntryDate] == DBNull.Value ? (DateTime?)null : DateTime.Parse(dr[recAcceptance.Fields.EntryDate].ToString());
                                t.ReviewDate = dr[recAcceptance.Fields.ReviewDate] == DBNull.Value ? (DateTime?)null : DateTime.Parse(dr[recAcceptance.Fields.ReviewDate].ToString());
                                t.sumValues = dr[recAcceptance.Fields.sumValues] == DBNull.Value ? (decimal?)null : decimal.Parse(dr[recAcceptance.Fields.sumValues].ToString());
                                t.CreatedDate = dr[recAcceptance.Fields.CreatedDate] == DBNull.Value ? (DateTime?)null : DateTime.Parse(dr[recAcceptance.Fields.CreatedDate].ToString());
                                t.CreatedBy = dr[recAcceptance.Fields.CreatedBy] == DBNull.Value ? string.Empty : dr[recAcceptance.Fields.CreatedBy].ToString();
                                t.UpdatedDate = dr[recAcceptance.Fields.UpdatedDate] == DBNull.Value ? (DateTime?)null : DateTime.Parse(dr[recAcceptance.Fields.UpdatedDate].ToString());
                                t.UpdatedBy = dr[recAcceptance.Fields.UpdatedBy] == DBNull.Value ? string.Empty : dr[recAcceptance.Fields.UpdatedBy].ToString();
                                t.Versi = dr[recAcceptance.Fields.Versi] == DBNull.Value ? (short?)null : short.Parse(dr[recAcceptance.Fields.Versi].ToString());
                                
                                tt.Add(t);
                                t.Dispose();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
            return tt;
        }

        public bool Save(recAcceptance master, List<recAcceptanceDetail> details)
        {
            bool result = false;
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                SqlTransaction txn = conn.BeginTransaction();
                try
                {
                    SqlCommand cmd = conn.CreateCommand();
                    cmd.CommandText = "INSERT INTO transactions.recAcceptance(AcceptancePeriod, SkNo, SkDate, EntryDate, ReviewDate, sumValues, CreatedDate, CreatedBy, UpdatedDate, UpdatedBy, Versi) VALUES(@AcceptancePeriod, @SkNo, @SkDate, @EntryDate, @ReviewDate, @sumValues, @CreatedDate, @CreatedBy, @UpdatedDate, @UpdatedBy, @Versi)";
                    cmd.CommandType = CommandType.Text;
                    cmd.Parameters.Add("@AcceptancePeriod", SqlDbType.Int).Value = master.AcceptancePeriod;
                    cmd.Parameters.Add("@SkNo", SqlDbType.VarChar).Value = master.SkNo;
                    cmd.Parameters.Add("@SkDate", SqlDbType.Date).Value = master.SkDate;
                    cmd.Parameters.Add("@EntryDate", SqlDbType.Date).Value = (object)master.EntryDate ?? DBNull.Value;
                    cmd.Parameters.Add("@ReviewDate", SqlDbType.Date).Value = (object)master.ReviewDate ?? DBNull.Value;
                    cmd.Parameters.Add("@sumValues", SqlDbType.Decimal).Value = (object)master.sumValues ?? DBNull.Value;
                    cmd.Parameters.Add("@CreatedDate", SqlDbType.DateTime).Value = (object)master.CreatedDate ?? DBNull.Value;
                    cmd.Parameters.Add("@CreatedBy", SqlDbType.VarChar).Value = (object)master.CreatedBy ?? DBNull.Value;
                    cmd.Parameters.Add("@UpdatedDate", SqlDbType.DateTime).Value = (object)master.UpdatedDate ?? DBNull.Value;
                    cmd.Parameters.Add("@UpdatedBy", SqlDbType.VarChar).Value = (object)master.UpdatedBy ?? DBNull.Value;
                    cmd.Parameters.Add("@Versi", SqlDbType.SmallInt).Value = (object)master.Versi ?? DBNull.Value;

                    cmd.Transaction = txn;
                    cmd.ExecuteNonQuery();
                    cmd.Dispose();

                    cmd = conn.CreateCommand();
                    cmd.CommandText = " SELECT MAX(AcceptanceId) AcceptanceId FROM transactions.recAcceptance WHERE CreatedBy = @CreatedBy";
                    cmd.Parameters.Add("@CreatedBy", SqlDbType.VarChar).Value = master.CreatedBy;

                    cmd.Transaction = txn;
                    var objAcceptanceID = cmd.ExecuteScalar(); // Get AcceptanceID
                    cmd.Dispose();

                    int acceptanceId = objAcceptanceID == DBNull.Value ? 0 : Convert.ToInt32(objAcceptanceID.ToString()); // Get AcceptanceID

                    cmd = conn.CreateCommand();
                    cmd.CommandText = " select ISNULL(MAX(AcceptanceDetailID),0) AcceptanceDetailID from transactions.recAcceptanceDetail ";

                    cmd.Transaction = txn;
                    var objAcceptanceDetailID = cmd.ExecuteScalar(); // Get AcceptanceDetailID
                    cmd.Dispose();

                    int acceptanceDetailId = objAcceptanceDetailID == DBNull.Value ? 0 : Convert.ToInt32(objAcceptanceDetailID.ToString()); // Get AcceptanceDetailID

                    details.ForEach(delegate(recAcceptanceDetail domain)
                    {
                        acceptanceDetailId = acceptanceDetailId + 1;
                        domain.AcceptanceDetailId = acceptanceDetailId;
                        domain.AcceptanceId = acceptanceId;

                        cmd = conn.CreateCommand();
                        cmd.CommandText = "INSERT INTO transactions.recAcceptanceDetail(AcceptanceDetailId, AcceptanceId, SectorCode, SubSectorCode, SubSubSectorCode, Level, KeyId, [Description], [Values], CreatedDate, CreatedBy, UpdatedDate, UpdatedBy, IsLeaf, IsExpand) VALUES(@AcceptanceDetailId, @AcceptanceId, @SectorCode, @SubSectorCode, @SubSubSectorCode, @Level, @KeyId, @Description, @Values, @CreatedDate, @CreatedBy, @UpdatedDate, @UpdatedBy, @IsLeaf, @IsExpand)";
                        cmd.CommandType = CommandType.Text;
                        cmd.Parameters.Add("@AcceptanceDetailId", SqlDbType.Int).Value = domain.AcceptanceDetailId;
                        cmd.Parameters.Add("@AcceptanceId", SqlDbType.Int).Value = domain.AcceptanceId;
                        cmd.Parameters.Add("@SectorCode", SqlDbType.Int).Value = (object)domain.SectorCode ?? DBNull.Value;
                        cmd.Parameters.Add("@SubSectorCode", SqlDbType.Int).Value = (object)domain.SubSectorCode ?? DBNull.Value;
                        cmd.Parameters.Add("@SubSubSectorCode", SqlDbType.Int).Value = (object)domain.SubSubSectorCode ?? DBNull.Value;
                        cmd.Parameters.Add("@Level", SqlDbType.Int).Value = (object)domain.Level ?? DBNull.Value;
                        cmd.Parameters.Add("@KeyId", SqlDbType.Int).Value = (object)domain.KeyId ?? DBNull.Value;
                        cmd.Parameters.Add("@Description", SqlDbType.VarChar).Value = (object)domain.Description ?? DBNull.Value;
                        cmd.Parameters.Add("@Values", SqlDbType.Decimal).Value = (object)domain.Values ?? DBNull.Value;
                        cmd.Parameters.Add("@CreatedDate", SqlDbType.DateTime).Value = (object)domain.CreatedDate ?? DBNull.Value;
                        cmd.Parameters.Add("@CreatedBy", SqlDbType.VarChar).Value = (object)domain.CreatedBy ?? DBNull.Value;
                        cmd.Parameters.Add("@UpdatedDate", SqlDbType.DateTime).Value = (object)domain.UpdatedDate ?? DBNull.Value;
                        cmd.Parameters.Add("@UpdatedBy", SqlDbType.VarChar).Value = (object)domain.UpdatedBy ?? DBNull.Value;
                        cmd.Parameters.Add("@IsLeaf", SqlDbType.Bit).Value = domain.IsLeaf;
                        cmd.Parameters.Add("@IsExpand", SqlDbType.Bit).Value = domain.IsExpand;

                        cmd.Transaction = txn;
                        cmd.ExecuteNonQuery();
                        cmd.Dispose();
                    });

                    result = true;
                    txn.Commit();
                }
                catch (Exception ex)
                {
                    txn.Rollback();
                    throw (ex);
                }
                finally
                {
                    if (conn.State == ConnectionState.Open) conn.Close();
                }


            }
            return result;
        }    
      
    }
}
